// HY11 23R1
#include <math.h>

#include "PlatformProperty.h"

// 消息ID
#define MSG_SUNCURTAINPOS_INACT_TIMEOUT 5003
#define MSG_SUNCURTAINPOS_STOP_MOVE 5005
#define MSG_ROW1_LEFT 1
#define MSG_ROW1_RIGHT 2
#define MSG_ROW2_LEFT 3
#define MSG_ROW2_RIGHT 4
#define MSG_ALL_AREA 5
//天窗位置范围 0~100（百分比）
#define WINDOW_POS_MIN 0
#define WINDOW_POS_MAX 100
#define DELAY_TIME 120 * 1000

//类名为动态拼接VehicleProperty + WINDOW_POS（信号名称）,信号名称更新时需同步更新。 类在函数中使用，需在函数前声明。
namespace ecarx::vhal::core::property::impl { class VehiclePropertyWINDOW_POS; }
//提取公用方法并使用this：方法在类中使用，需在类前面声明
PropertyStatus getRow1LeftStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr);
PropertyStatus getRow1RightStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr);
PropertyStatus getRow2LeftStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr);
PropertyStatus getRow2RightStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr);
PropertyStatus getAllAreaStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr);

static sdb::UsgModSts1 lastUsgModSunCurtain = sdb::UsgModSts1::UsgModAbdnd;
static sdb::UsgModSts1 lastUsgModRow1Left = sdb::UsgModSts1::UsgModAbdnd;
static sdb::UsgModSts1 lastUsgModRow1Right = sdb::UsgModSts1::UsgModAbdnd;
static sdb::UsgModSts1 lastUsgModRow2Left = sdb::UsgModSts1::UsgModAbdnd;
static sdb::UsgModSts1 lastUsgModRow2Right = sdb::UsgModSts1::UsgModAbdnd;
static sdb::UsgModSts1 lastUsgModAllArea = sdb::UsgModSts1::UsgModAbdnd;


MAPPING_VALUE(int,
              sdb::WinAndRoofAndCurtPosnTyp,
              sdb::WinAndRoofAndCurtPosnTyp::ClsFull)
MAPPING_ITEM(0, sdb::WinAndRoofAndCurtPosnTyp::ClsFull)
MAPPING_ITEM(4, sdb::WinAndRoofAndCurtPosnTyp::PercOpen4)
MAPPING_ITEM(8, sdb::WinAndRoofAndCurtPosnTyp::PercOpen8)
MAPPING_ITEM(12, sdb::WinAndRoofAndCurtPosnTyp::PercOpen12)
MAPPING_ITEM(16, sdb::WinAndRoofAndCurtPosnTyp::PercOpen16)
MAPPING_ITEM(20, sdb::WinAndRoofAndCurtPosnTyp::PercOpen20)
MAPPING_ITEM(24, sdb::WinAndRoofAndCurtPosnTyp::PercOpen24)
MAPPING_ITEM(28, sdb::WinAndRoofAndCurtPosnTyp::PercOpen28)
MAPPING_ITEM(32, sdb::WinAndRoofAndCurtPosnTyp::PercOpen32)
MAPPING_ITEM(36, sdb::WinAndRoofAndCurtPosnTyp::PercOpen36)
MAPPING_ITEM(40, sdb::WinAndRoofAndCurtPosnTyp::PercOpen40)
MAPPING_ITEM(44, sdb::WinAndRoofAndCurtPosnTyp::PercOpen44)
MAPPING_ITEM(48, sdb::WinAndRoofAndCurtPosnTyp::PercOpen48)
MAPPING_ITEM(52, sdb::WinAndRoofAndCurtPosnTyp::PercOpen52)
MAPPING_ITEM(56, sdb::WinAndRoofAndCurtPosnTyp::PercOpen56)
MAPPING_ITEM(60, sdb::WinAndRoofAndCurtPosnTyp::PercOpen60)
MAPPING_ITEM(64, sdb::WinAndRoofAndCurtPosnTyp::PercOpen64)
MAPPING_ITEM(68, sdb::WinAndRoofAndCurtPosnTyp::PercOpen68)
MAPPING_ITEM(72, sdb::WinAndRoofAndCurtPosnTyp::PercOpen72)
MAPPING_ITEM(76, sdb::WinAndRoofAndCurtPosnTyp::PercOpen76)
MAPPING_ITEM(80, sdb::WinAndRoofAndCurtPosnTyp::PercOpen80)
MAPPING_ITEM(84, sdb::WinAndRoofAndCurtPosnTyp::PercOpen84)
MAPPING_ITEM(88, sdb::WinAndRoofAndCurtPosnTyp::PercOpen88)
MAPPING_ITEM(92, sdb::WinAndRoofAndCurtPosnTyp::PercOpen92)
MAPPING_ITEM(96, sdb::WinAndRoofAndCurtPosnTyp::PercOpen96)
MAPPING_ITEM(100, sdb::WinAndRoofAndCurtPosnTyp::OpenFull)
MAPPING_END

MAPPING_VALUE(sdb::WinAndRoofAndCurtPosnTyp, int, 0)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::ClsFull, 0)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen4, 4)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen8, 8)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen12, 12)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen16, 16)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen20, 20)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen24, 24)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen28, 28)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen32, 32)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen36, 36)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen40, 40)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen44, 44)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen48, 48)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen52, 52)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen56, 56)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen60, 60)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen64, 64)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen68, 68)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen72, 72)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen76, 76)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen80, 80)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen84, 84)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen88, 88)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen92, 92)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::PercOpen96, 96)
MAPPING_ITEM(sdb::WinAndRoofAndCurtPosnTyp::OpenFull, 100)
MAPPING_END

static int convertToPercent(int32_t value) {
    int i_Value = 0;
    if ((value >= 10) && (value <= 100)) {
        i_Value = (int)floor((value + 2) / 4) * 4;
    } else if (value > 100) {
        i_Value = 100;
    }
    VHALOG.d("WINDOW_POS convertToPercent : value[%d], i_Value[%d]", value,
          i_Value);
    return i_Value;
}

static int winPosConvertToPercent(int input)
{
    int output = 0;
    if (input >= 0 && input <= 100) {
        output = (int)floor((input + 2) / 4) * 4;
        VHALOG.d("winPosConvertToPercent WINDOW_POS : input[%d], output[%d]", input, output);
    } else if (input > 100) {
        output = 100;
        VHALOG.d("winPosConvertToPercent WINDOW_POS : input[%d], out of range, return output[%d]", input, output);
    }
    return output;
}

// [SW_FC_009_016] Vehicle 车窗-天窗遮阳帘控制、车窗控制
SYSTEM_READ_WRITE_PROPERTY(WINDOW_POS, int32_t) {
     // 遮阳帘控制
    builder.area(VehicleAreaWindow::ROOF_TOP_2)
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
                auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
                auto cc177 = SIGNAL.getcarconfig177();

                VHALOG.d("WINDOW_POS SUNCURTAIN : status Change carmod[%d], usgmod[%d], cc177[%d]", carmod, usgmod, cc177);
                if (SIGNAL.carConfigIs(SignalRX::carconfig177,
                                       sdb::CarConfig177::_02,
                                       sdb::CarConfig177::_05)) {
                    if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd) &&
                        SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                         sdb::CarModSts1::CarModCrash,
                                         sdb::CarModSts1::CarModDyno)) {
                        removeMsg(MSG_SUNCURTAINPOS_INACT_TIMEOUT);
                        VHALOG.d("WINDOW_POS SUNCURTAIN : remove MSG_SUNCURTAINPOS_INACT_TIMEOUT");
                        if (lastUsgModSunCurtain != sdb::UsgModSts1::UsgModInActv &&
                            SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                            sendMsg(MSG_SUNCURTAINPOS_INACT_TIMEOUT, DELAY_TIME);
                            VHALOG.d("WINDOW_POS SUNCURTAIN : sendMsg MSG_SUNCURTAINPOS_INACT_TIMEOUT");
                        }
                        lastUsgModSunCurtain = usgmod;
                        VHALOG.d("WINDOW_POS SUNCURTAIN : PropertyStatus::Active");
                        return PropertyStatus::Active;
                    }
                    VHALOG.d("WINDOW_POS SUNCURTAIN : PropertyStatus::NotActive");
                    return PropertyStatus::NotActive;
                }
                VHALOG.d("WINDOW_POS SUNCURTAIN : PropertyStatus::NotAvailable");
                return PropertyStatus::NotAvailable;
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            []([[maybe_unused]] int32_t last) {
                return last;
            })
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("WINDOW_POS SUNCURTAIN : setValue[%d]", value);
            removeMsg(MSG_SUNCURTAINPOS_STOP_MOVE);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("WINDOW_POS SUNCURTAIN : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }
            int percent = convertToPercent(value);
            sdb::WinAndRoofAndCurtPosnTyp reqCurt =
                mappingValue(percent, sdb::WinAndRoofAndCurtPosnTyp::ClsFull);
            VHALOG.d("WINDOW_POS SUNCURTAIN : percent[%d], reqCurt[%d]", percent,
                  toInt(reqCurt));
            SIGNAL.setSunCurtOpenPosnReq(reqCurt);
        })
        .subscribeSignals([this]() { //AUD诊断
                // 收到SunCurtMvngSts == 0[FALSE]时，遮阳帘停止移动，LCFG_TimeOfCurtainNotMove秒后，读取位置信息，更新实时位置。
                sdb::Boolean suncurtMoveSts = SIGNAL.getSunCurtMvngSts();
                VHALOG.d("WINDOW_POS SUNCURTAIN : suncurtMoveSts:[%d]",
                      toInt(suncurtMoveSts));
                removeMsg(MSG_SUNCURTAINPOS_STOP_MOVE);
                //遮阳帘停止移动，LCFG_TimeOfCurtainNotMove秒后，读取位置信息，更新实时位置。
                if (suncurtMoveSts == sdb::Boolean::FALSE) {
                    uint32_t TimeOfCurtainNotMove =
                        lcfg::LocalConfig::getInstance().getInt<int32_t>(
                            lcfg::LCFG_TimeOfCurtainNotMove);
                    sendMsg(MSG_SUNCURTAINPOS_STOP_MOVE, TimeOfCurtainNotMove);
                }
            },
            SignalRX::SunCurtMvngSts)
        .onMsgEvent(MSG_SUNCURTAINPOS_INACT_TIMEOUT,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROOF_TOP_2),
                            PropertyStatus::NotActive);
                    })
        .onMsgEvent(MSG_SUNCURTAINPOS_STOP_MOVE, [this]() {
            // LCFG_TimeOfCurtainNotMove 秒后，读取位置信息，更新实时位置。
            sdb::WinAndRoofAndCurtPosnTyp sSunCurtPosnSts =
                SIGNAL.getSunCurtPosnSts();
            int32_t curtPos = mappingValue(sSunCurtPosnSts, 0);
            VHALOG.d("WINDOW_POS SUNCURTAIN MSG_SUNCURTAINPOS_STOP_MOVE:sSunCurtPosnSts:[%d], curtPos[%d]",
                  toInt(sSunCurtPosnSts), curtPos);
            setValue(static_cast<int32_t>(VehicleAreaWindow::ROOF_TOP_2),
                     curtPos, false);
        })
        .area(VehicleAreaWindow::ROW_1_LEFT)     //车窗控制 - 前左
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                return getRow1LeftStatus(this);
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            []([[maybe_unused]] int32_t last) {
                auto drvrSts = mappingValue(SIGNAL.getWinPosnStsAtDrvr(), 0);
                auto passSts = mappingValue(SIGNAL.getWinPosnStsAtPass(), 0);
                if (SIGNAL.carConfigIs(SignalRX::carconfig8, sdb::CarConfig8::_01)) {
                    VHALOG.d("withValueBySignals WINDOW_POS ROW_1_LEFT : last[%d], drvrSts:[%d]",
                      last, drvrSts);
                    return drvrSts;
                } else {
                    VHALOG.d("withValueBySignals WINDOW_POS ROW_1_LEFT : last[%d], drvrSts:[%d]",
                      last, passSts);
                return passSts;
                }
            },
            SignalRX::WinPosnStsAtDrvr, SignalRX::WinPosnStsAtPass)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("onSetProperty WINDOW_POS ROW_1_LEFT : setValue[%d]", value);
            removeMsg(MSG_ROW1_LEFT);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("onSetProperty WINDOW_POS ROW_1_LEFT : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }
            int percent = winPosConvertToPercent(value);
            sdb::WinAndRoofAndCurtPosnTyp reqDrvr =
                mappingValue(percent, sdb::WinAndRoofAndCurtPosnTyp::ClsFull);
            VHALOG.d("onSetProperty WINDOW_POS ROW_1_LEFT : percent[%d], reqDrvr[%d]", percent,
                  toInt(reqDrvr));
            if (SIGNAL.carConfigIs(SignalRX::carconfig8, sdb::CarConfig8::_01)) {
                SIGNAL.setWinOpenDrvrReq(reqDrvr);
            } else {
                SIGNAL.setWinOpenPassReq(reqDrvr);
            }

        })
        .onMsgEvent(MSG_ROW1_LEFT,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROW_1_LEFT),
                            PropertyStatus::NotActive);
        })
        .area(VehicleAreaWindow::ROW_1_RIGHT)       //车窗控制 - 前右
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                return getRow1RightStatus(this);
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            []([[maybe_unused]] int32_t last) {
                auto drvrSts = mappingValue(SIGNAL.getWinPosnStsAtDrvr(), 0);
                auto passSts = mappingValue(SIGNAL.getWinPosnStsAtPass(), 0);
                if (SIGNAL.carConfigIs(SignalRX::carconfig8, sdb::CarConfig8::_01)) {
                    VHALOG.d("withValueBySignals WINDOW_POS ROW_1_RIGHT : last[%d], passSts:[%d]",
                      last, passSts);
                    return passSts;
                } else {
                    VHALOG.d("withValueBySignals WINDOW_POS ROW_1_RIGHT : last[%d], passSts:[%d]",
                      last, drvrSts);
                    return drvrSts;
                }    
            },
            SignalRX::WinPosnStsAtDrvr, SignalRX::WinPosnStsAtPass)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("onSetProperty WINDOW_POS ROW_1_RIGHT : setValue[%d]", value);
            removeMsg(MSG_ROW1_RIGHT);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("onSetProperty WINDOW_POS ROW_1_RIGHT : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }
            int percent = winPosConvertToPercent(value);
            sdb::WinAndRoofAndCurtPosnTyp reqPass =
                mappingValue(percent, sdb::WinAndRoofAndCurtPosnTyp::ClsFull);
            VHALOG.d("onSetProperty WINDOW_POS ROW_1_RIGHT : percent[%d], reqPass[%d]", percent,
                  toInt(reqPass));
            if (SIGNAL.carConfigIs(SignalRX::carconfig8, sdb::CarConfig8::_01)) {
                SIGNAL.setWinOpenPassReq(reqPass);
            } else {
                SIGNAL.setWinOpenDrvrReq(reqPass);
            }

        })
        .onMsgEvent(MSG_ROW1_RIGHT,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROW_1_RIGHT),
                            PropertyStatus::NotActive);
        })
        .area(VehicleAreaWindow::ROW_2_LEFT)        //车窗控制 - 后左
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                return getRow2LeftStatus(this);
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            []([[maybe_unused]] int32_t last) {
                auto releSts = mappingValue(SIGNAL.getWinPosnStsAtReLe(), 0);
                VHALOG.d("withValueBySignals WINDOW_POS ROW_2_LEFT : last[%d], releSts:[%d]",
                      last, releSts);
                return releSts;
            },
            SignalRX::WinPosnStsAtReLe)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("onSetProperty WINDOW_POS ROW_2_LEFT : setValue[%d]", value);
            removeMsg(MSG_ROW2_LEFT);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("onSetProperty WINDOW_POS ROW_2_LEFT : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }
            int percent = winPosConvertToPercent(value);
            sdb::WinAndRoofAndCurtPosnTyp reqRele =
                mappingValue(percent, sdb::WinAndRoofAndCurtPosnTyp::ClsFull);
            VHALOG.d("onSetProperty WINDOW_POS ROW_2_LEFT : percent[%d], reqRele[%d]", percent,
                  toInt(reqRele));
            SIGNAL.setWinOpenReLeReq(reqRele);
        })
        .onMsgEvent(MSG_ROW2_LEFT,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROW_2_LEFT),
                            PropertyStatus::NotActive);
        })
        .area(VehicleAreaWindow::ROW_2_RIGHT)       //车窗控制 - 后右
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                return getRow2RightStatus(this);
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals(
            []([[maybe_unused]] int32_t last) {
                auto reriSts = mappingValue(SIGNAL.getWinPosnStsAtReRi(), 0);
                VHALOG.d("withValueBySignals WINDOW_POS ROW_2_RIGHT : last[%d], reriSts:[%d]",
                      last, reriSts);
                return reriSts;
            },
            SignalRX::WinPosnStsAtReRi)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("onSetProperty WINDOW_POS ROW_2_RIGHT : setValue[%d]", value);
            removeMsg(MSG_ROW2_RIGHT);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("onSetProperty WINDOW_POS ROW_2_RIGHT : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }
            int percent = winPosConvertToPercent(value);
            sdb::WinAndRoofAndCurtPosnTyp reqReri =
                mappingValue(percent, sdb::WinAndRoofAndCurtPosnTyp::ClsFull);
            VHALOG.d("onSetProperty WINDOW_POS ROW_2_RIGHT : percent[%d], reqReri[%d]", percent,
                  toInt(reqReri));
            SIGNAL.setWinOpenReRiReq(reqReri);
        })
        .onMsgEvent(MSG_ROW2_RIGHT,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROW_2_RIGHT),
                            PropertyStatus::NotActive);
        })
        .area(VehicleAreaWindow::ROW_1_LEFT | VehicleAreaWindow::ROW_1_RIGHT | VehicleAreaWindow::ROW_2_LEFT | VehicleAreaWindow::ROW_2_RIGHT)    //车窗控制 - 一键操作所有车窗&&一键通风
        .range(WINDOW_POS_MIN, WINDOW_POS_MAX)
        .initValue([]() { return 0; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& last) {
                return getAllAreaStatus(this);
            },
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1)
        .withValueBySignals([]([[maybe_unused]] int32_t last) { return last; })
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("onSetProperty WINDOW_POS ROW_1&&ROW_2 : setValue[%d]", value);
            // VFC 开启
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("onSetProperty WINDOW_POS ROW_1&&ROW_2 : setCB_VFC_MirrCtrlForHmiCen");
                SIGNAL.setCB_VFC_MirrCtrlForHmiCen(sdb::OnOff1::On);
            }

            auto newValue = sdb::WinAndRoofAndCurtPosnTyp::ClsFull;
            if (value == 0) {       //一键操作所有车窗
                newValue = sdb::WinAndRoofAndCurtPosnTyp::ClsFull;
            } else if (value == 100) {
                newValue = sdb::WinAndRoofAndCurtPosnTyp::OpenFull;
            } else {                //一键通风只发5
                newValue = sdb::WinAndRoofAndCurtPosnTyp::PercOpen16;
            }

            PropertyStatus row2Sts = PropertyStatus::NotAvailable;
            row2Sts = getStatus(static_cast<int32_t>(VehicleAreaWindow::ROW_2_LEFT));
            if (row2Sts == PropertyStatus::Active) {
                SIGNAL.setWinOpenDrvrReq(newValue);
                SIGNAL.setWinOpenPassReq(newValue);
                SIGNAL.setWinOpenReLeReq(newValue);
                SIGNAL.setWinOpenReRiReq(newValue);
                VHALOG.d("onSetProperty WINDOW_POS ROW_1&&ROW_2 : reqDrvr==reqPass==reqRele==reqReri[%d]", 
                    toInt(newValue));
            } else {
                SIGNAL.setWinOpenDrvrReq(newValue);
                SIGNAL.setWinOpenPassReq(newValue);
                VHALOG.d("onSetProperty WINDOW_POS ROW_1&&ROW_2 : reqDrvr==reqPass[%d]", 
                    toInt(newValue));
            }
        })
        .onMsgEvent(MSG_ALL_AREA,
                    [this]() {
                        // UsgMode ==
                        // Inactive，天窗可以工作2分钟，随后，功能置灰用户无法操作。
                        updateAreaStatus(
                            static_cast<int32_t>(VehicleAreaWindow::ROW_1_LEFT | VehicleAreaWindow::ROW_1_RIGHT | VehicleAreaWindow::ROW_2_LEFT | VehicleAreaWindow::ROW_2_RIGHT),
                            PropertyStatus::NotActive);
        });
}

PropertyStatus getRow1LeftStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr) {
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();

    VHALOG.d("getRow1Status WINDOW_POS ROW_1_LEFT : status Change carmod[%d], usgmod[%d]", carmod, usgmod);
        if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
            if (lastUsgModRow1Left != sdb::UsgModSts1::UsgModInActv && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                thisPtr->removeMsg(MSG_ROW1_LEFT);  
                VHALOG.d("getRow1Status WINDOW_POS ROW_1_LEFT : remove MSG_ROW1_LEFT");
                thisPtr->sendMsg(MSG_ROW1_LEFT, DELAY_TIME);
                VHALOG.d("getRow1Status WINDOW_POS ROW_1_LEFT : sendMsg MSG_ROW1_LEFT");
            }
            lastUsgModRow1Left = usgmod;
            VHALOG.d("getRow1Status WINDOW_POS ROW_1_LEFT : PropertyStatus::Active");
            return PropertyStatus::Active;
        }
        VHALOG.d("getRow1Status WINDOW_POS ROW_1_LEFT : PropertyStatus::NotActive");
        return PropertyStatus::NotActive;

}

PropertyStatus getRow1RightStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr) {
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();

    VHALOG.d("getRow1Status WINDOW_POS ROW_1_RIGHT : status Change carmod[%d], usgmod[%d]", carmod, usgmod);
        if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
            if (lastUsgModRow1Right != sdb::UsgModSts1::UsgModInActv && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                thisPtr->removeMsg(MSG_ROW1_RIGHT);
                VHALOG.d("getRow1Status WINDOW_POS ROW_1_RIGHT : remove MSG_ROW1_RIGHT");
                thisPtr->sendMsg(MSG_ROW1_RIGHT, DELAY_TIME);
                VHALOG.d("getRow1Status WINDOW_POS ROW_1_RIGHT : sendMsg MSG_ROW1_RIGHT");
            }
            lastUsgModRow1Right = usgmod;
            VHALOG.d("getRow1Status WINDOW_POS ROW_1_RIGHT : PropertyStatus::Active");
            return PropertyStatus::Active;
        }
        VHALOG.d("getRow1Status WINDOW_POS ROW_1_RIGHT : PropertyStatus::NotActive");
        return PropertyStatus::NotActive;
}

PropertyStatus getRow2LeftStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr) {
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
    auto cc2 = SIGNAL.getcarconfig2();

    VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : status Change carmod[%d], usgmod[%d], cc2[%d]", carmod, usgmod, cc2);
        if (SIGNAL.carConfigIs(SignalRX::carconfig2, sdb::CarConfig2::_01, sdb::CarConfig2::_02)) {
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                if (lastUsgModRow2Left != sdb::UsgModSts1::UsgModInActv && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                    thisPtr->removeMsg(MSG_ROW2_LEFT); 
                    VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : remove MSG_ROW2_LEFT"); 
                    thisPtr->sendMsg(MSG_ROW2_LEFT, DELAY_TIME);
                    VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : sendMsg MSG_ROW2_LEFT");
                }
                lastUsgModRow2Left = usgmod;
                VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : PropertyStatus::Active");
                return PropertyStatus::Active;
            } else {
                VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : PropertyStatus::NotActive");
                return PropertyStatus::NotActive;
            }
        } else {
            VHALOG.d("getRow2Status WINDOW_POS ROW_2_LEFT : PropertyStatus::NotAvailable");
            return PropertyStatus::NotAvailable;
        }
}

PropertyStatus getRow2RightStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr) {
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
    auto cc2 = SIGNAL.getcarconfig2();

    VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : status Change carmod[%d], usgmod[%d], cc2[%d]", carmod, usgmod, cc2);
        if (SIGNAL.carConfigIs(SignalRX::carconfig2, sdb::CarConfig2::_01, sdb::CarConfig2::_02)) {
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                if (lastUsgModRow2Right != sdb::UsgModSts1::UsgModInActv && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                    thisPtr->removeMsg(MSG_ROW2_RIGHT);
                    VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : remove MSG_ROW2_RIGHT");
                    thisPtr->sendMsg(MSG_ROW2_RIGHT, DELAY_TIME);
                    VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : sendMsg MSG_ROW2_RIGHT");
                }
                lastUsgModRow2Right = usgmod;
                VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : PropertyStatus::Active");
                return PropertyStatus::Active;
            } else {
                VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : PropertyStatus::NotActive");
                return PropertyStatus::NotActive;
            }
        } else {
            VHALOG.d("getRow2Status WINDOW_POS ROW_2_RIGHT : PropertyStatus::NotAvailable");
            return PropertyStatus::NotAvailable;
        }
}

PropertyStatus getAllAreaStatus(ecarx::vhal::core::property::impl::VehiclePropertyWINDOW_POS* thisPtr) {
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();

    VHALOG.d("getRow1Status WINDOW_POS ROW_1&&ROW_2 : status Change carmod[%d], usgmod[%d]", carmod, usgmod);
        if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
            if (lastUsgModAllArea != sdb::UsgModSts1::UsgModInActv && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModInActv)) {
                thisPtr->removeMsg(MSG_ALL_AREA);
                VHALOG.d("getRow1Status WINDOW_POS ROW_1&&ROW_2 : remove MSG_ROW1_RIGHT");
                thisPtr->sendMsg(MSG_ALL_AREA, DELAY_TIME);
                VHALOG.d("getRow1Status WINDOW_POS ROW_1&&ROW_2 : sendMsg MSG_ROW1_RIGHT");
            }
            lastUsgModAllArea = usgmod;
            VHALOG.d("getRow1Status WINDOW_POS ROW_1&&ROW_2 : PropertyStatus::Active");
            return PropertyStatus::Active;
        }
        VHALOG.d("getRow1Status WINDOW_POS ROW_1&&ROW_2 : PropertyStatus::NotActive");
        return PropertyStatus::NotActive;
}